/*
 * Copyright 2011 The Rusted Roof, LLC.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package org.proteusframework.platformservice.persistence.messagebean;

import org.proteusframework.core.base.Namespace;
import org.proteusframework.core.util.Assert;
import org.proteusframework.platformservice.persistence.api.messagebean.IMessageBeanProperty;

import java.util.Properties;

/**
 * Package private {@link IMessageBeanProperty} concrete implementation. Developer must use the
 * {@link MessageBeanBuilder} to create instances of {@link org.proteusframework.platformservice.persistence.api.messagebean.IMessageBeanDescriptor}.
 *
 * @author Tacoma Four
 */
final class MessageBeanProperty extends Namespace implements IMessageBeanProperty
{
    private final DataType dataType;
    private final int length;
    private final int precision;

    private final boolean nullable;
    private final boolean primaryKeyMember;

    private String description;
    private Properties metadata = new Properties();

    MessageBeanProperty(String family,
                        String propertyName,
                        DataType dataType)
    {
        super(family, propertyName);
        Assert.parameterNotNull(dataType, "Parameter 'dataType' must not be null");
        this.dataType = dataType;
        this.nullable = true;
        this.primaryKeyMember = false;
        this.length = (DataType.CharType == dataType) ? 1 : 0;
        this.precision = 0;
    }

    MessageBeanProperty(String family,
                        String propertyName,
                        DataType dataType,
                        int length)
    {
        super(family, propertyName);
        Assert.parameterNotNull(dataType, "Parameter 'dataType' must not be null");
        this.dataType = dataType;
        this.length = (length >= 0)
                ? (DataType.CharType == dataType) ? 1 : length
                : 0;
        this.precision = 0;
        this.nullable = true;
        this.primaryKeyMember = false;
    }

    MessageBeanProperty(String family,
                        String propertyName,
                        DataType dataType,
                        int length,
                        int precision)
    {
        super(family, propertyName);
        Assert.parameterNotNull(dataType, "Parameter 'dataType' must not be null");
        this.dataType = dataType;
        this.length = (length >= 0)
                ? (DataType.CharType == dataType) ? 1 : length
                : 0;
        this.precision = (precision >= 0) ? precision : 0;
        this.nullable = true;
        this.primaryKeyMember = false;
    }

    MessageBeanProperty(String family,
                        String propertyName,
                        DataType dataType,
                        boolean primaryKeyMember)
    {
        super(family, propertyName);
        Assert.parameterNotNull(dataType, "Parameter 'dataType' must not be null");
        this.dataType = dataType;
        this.length = (DataType.CharType == dataType) ? 1 : 0;
        this.precision = 0;
        this.nullable = false;
        this.primaryKeyMember = primaryKeyMember;
    }

    MessageBeanProperty(String family,
                        String propertyName,
                        DataType dataType,
                        int length,
                        boolean primaryKeyMember)
    {
        super(family, propertyName);
        Assert.parameterNotNull(dataType, "Parameter 'dataType' must not be null");
        this.dataType = dataType;
        this.length = (length >= 0)
                ? (DataType.CharType == dataType) ? 1 : length
                : 0;
        this.precision = 0;
        this.nullable = false;
        this.primaryKeyMember = primaryKeyMember;
    }

    MessageBeanProperty(String family,
                        String propertyName,
                        DataType dataType,
                        int length,
                        int precision,
                        boolean primaryKeyMember)
    {
        super(family, propertyName);
        Assert.parameterNotNull(dataType, "Parameter 'dataType' must not be null");
        this.dataType = dataType;
        this.length = (length >= 0)
                ? (DataType.CharType == dataType) ? 1 : length
                : 0;
        this.precision = (precision >= 0) ? precision : 0;
        this.nullable = false;
        this.primaryKeyMember = primaryKeyMember;
    }

    MessageBeanProperty(String family,
                        String propertyName,
                        DataType dataType,
                        boolean primaryKeyMember,
                        boolean nullable)
    {
        super(family, propertyName);
        Assert.parameterNotNull(dataType, "Parameter 'dataType' must not be null");
        this.dataType = dataType;
        this.length = (DataType.CharType == dataType) ? 1 : 0;
        this.precision = 0;
        this.nullable = nullable;
        this.primaryKeyMember = primaryKeyMember;
    }

    MessageBeanProperty(String family,
                        String propertyName,
                        DataType dataType,
                        int length,
                        boolean primaryKeyMember,
                        boolean nullable)
    {
        super(family, propertyName);
        Assert.parameterNotNull(dataType, "Parameter 'dataType' must not be null");
        this.dataType = dataType;
        this.length = (length >= 0)
                ? (DataType.CharType == dataType) ? 1 : length
                : 0;
        this.precision = 0;
        this.nullable = nullable;
        this.primaryKeyMember = primaryKeyMember;
    }

    MessageBeanProperty(String family,
                        String propertyName,
                        DataType dataType,
                        int length,
                        int precision,
                        boolean primaryKeyMember,
                        boolean nullable)
    {
        super(family, propertyName);
        Assert.parameterNotNull(dataType, "Parameter 'dataType' must not be null");
        this.dataType = dataType;
        this.length = (length >= 0)
                ? (DataType.CharType == dataType) ? 1 : length
                : 0;
        this.precision = (precision >= 0) ? precision : 0;
        this.nullable = nullable;
        this.primaryKeyMember = primaryKeyMember;
    }

    @Override
    public String getName()
    {
        return getId();
    }

    @Override
    public DataType getDataType()
    {
        return dataType;
    }

    @Override
    public int getLength()
    {
        return length;
    }

    @Override
    public boolean isNullable()
    {
        return nullable;
    }

    @Override
    public String getDescription()
    {
        return description;
    }

    public void setDescription(String description)
    {
        this.description = description;
    }

    @Override
    public boolean isPrimaryKeyMember()
    {
        return primaryKeyMember;
    }

    @Override
    public Properties getMetadata()
    {
        return metadata;
    }

    @Override
    public int getPrecision()
    {
        return precision;
    }

    @Override
    public String toString()
    {
        return "MessageBeanProperty{" +
                "dataType=" + dataType +
                ", length=" + length +
                ", precision=" + precision +
                ", nullable=" + nullable +
                ", primaryKeyMember=" + primaryKeyMember +
                ", description='" + description + '\'' +
                ", metadata=" + metadata +
                "} " + super.toString();
    }
}
